import 'package:family_expense/features/authentication/widgets/password_login.dart';
import 'package:flutter/material.dart';
import 'package:material_design_icons_flutter/material_design_icons_flutter.dart';
import 'package:my_flutter_core/my_flutter_core.dart';

/// IMPORTANT!!!
/// Even we do not use [setState] method here we still need the [StatefulWidget].
/// Because [Form] and [TextFormField] work with [StatefulWidget] only.
/// Otherwise once you tap on a [TextFormField] the keyboard closes after it opens right away.
class AccountRegister extends StatefulWidget {
  const AccountRegister({super.key});

  @override
  State<AccountRegister> createState() => _AccountRegisterState();
}

class _AccountRegisterState extends State<AccountRegister> {
  final TextEditingController _passwordController = TextEditingController();
  final GlobalKey<FormState> _formKey = GlobalKey<FormState>();

  late String _username;
  late String _password;
  late String _fullName;

  @override
  void dispose() {
    _passwordController.dispose();

    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: const Text('注册新账号')),
      body: _buildForm(),
    );
  }

  /// Builds the input form.
  Widget _buildForm() {
    // DO NOT PUT [Form] in [ListView]. Uses [SingleChildScrollView] instead.
    // Textfield in gallery gets reset if scrolled out of view.
    // https://github.com/flutter/flutter/issues/11500
    return Form(
      key: _formKey,
      child: SingleChildScrollView(
        padding: const EdgeInsets.all(16.0),
        child: Column(
          crossAxisAlignment: CrossAxisAlignment.stretch,
          children: [
            const SizedBox(height: 20.0),
            TextFormField(
              keyboardType: TextInputType.number,
              decoration: const InputDecoration(
                hintText: '请输入手机号用于登录',
                prefixIcon: Icon(Icons.phone_android),
              ),
              validator: (value) => FormTextFieldValidator(
                '手机号',
                value,
                patterns: [
                  ValidatorPattern(
                    RegularExpressionPattern.checkMobilePhoneNumber,
                    '请输入正确格式的手机号',
                    matchCheck: false,
                  ),
                ],
              ).validate(),
              onSaved: (value) => _username = value!,
            ),
            const SizedBox(height: 20.0),
            TextFormField(
              keyboardType: TextInputType.text,
              decoration: InputDecoration(
                hintText: '请输入名称',
                prefixIcon: Icon(MdiIcons.account),
              ),
              validator: (value) =>
                  FormTextFieldValidator('名称', value).validate(),
              onSaved: (value) => _fullName = value!,
            ),
            const SizedBox(height: 20.0),
            TextFormField(
              controller: _passwordController,
              obscureText: true,
              decoration: const InputDecoration(
                hintText: '请输入密码（长度至少${User.passwordMinLength}位）',
                prefixIcon: Icon(Icons.lock_open),
              ),
              validator: (value) => FormTextFieldValidator(
                '密码',
                value,
                minLength: User.passwordMinLength,
                maxLength: User.passwordMaxLength,
              ).validate(),
              onSaved: (value) => _password = value!,
            ),
            const SizedBox(height: 20.0),
            TextFormField(
              obscureText: true,
              decoration: const InputDecoration(
                hintText: '请再次输入密码',
                prefixIcon: Icon(Icons.lock_open),
              ),
              validator: (value) => FormTextFieldValidator(
                '确认密码',
                value,
                label2: '密码',
                value2: _passwordController.text,
              ).validate(),
            ),
            Row(
              mainAxisAlignment: MainAxisAlignment.spaceBetween,
              children: [
                TextButton(
                  child: const Text('没有短信验证码？'),
                  onPressed: () => showToast('因本系统没有预算引入付费短信功能'),
                ),
                TextButton(
                  child: const Text('已有账号去登录'),
                  onPressed: () => NavigatorHelper.pushAndRemoveUntil(
                    context,
                    const PasswordLogin(),
                    (route) => false,
                  ),
                ),
              ],
            ),
            Container(
              padding: const EdgeInsets.only(top: 20.0),
              height: 60.0,
              child: PressStatusButton(
                onPressed: _register,
                disabledChild: const Text(
                  '正在注册',
                  style: TextStyle(fontSize: 20.0),
                ),
                child: const Text('注 册', style: TextStyle(fontSize: 20.0)),
              ),
            ),
          ],
        ),
      ),
    );
  }

  /// Registers the input user data.
  Future<void> _register() async {
    // Validate returns true if the form is valid, or false otherwise.
    if (!_formKey.currentState!.validate()) {
      showToast('请正确填写各项信息');
      return;
    }

    // Creates the [UserService] with scaffold state.
    final authenticationService = AuthService();

    // Saves current form.
    _formKey.currentState!.save();

    // Checks on the username existing first.
    final usernameExists = await authenticationService.checkOnUsername(
      _username,
    );

    // If the username exists then need to show the alert.
    if (usernameExists) {
      showToast('该手机号已被占用，请更换后重试。');
    } else {
      // Registers the username and goes to the complete page if successful.
      final success = await authenticationService.register(
        _username,
        _password,
        _fullName,
      );

      if (success && mounted) {
        AuthStateService.instance.saveCurrentUsername(username: _username);

        // DO NOT use BuildContext across asynchronous gaps.
        // https://dart-lang.github.io/linter/lints/use_build_context_synchronously.html
        NavigatorHelper.pushReplacement(
          context,
          const AccountRegisterCompleted(),
        );
      }
    }
  }
}

/// Once the account register is completed is widget will be pushed.
/// It shows the successful info and guides user to the [PasswordLogin].
///
/// The entire navigation flow is: Login pushNamed-> Register pushReplacementNamed-> Completed pushNamedAndRemoveUntil-> Login.
/// Explain:
/// - [pushNamed] from Login to Register. User can go back to Login.
/// - [pushReplacementNamed] from Register to Completed. User cannot go back to Register but go to the Login instead.
/// - [pushNamedAndRemoveUntil] User only can stay with Login. No other history stack available.
class AccountRegisterCompleted extends StatelessWidget {
  const AccountRegisterCompleted({super.key});

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: const Text('注册成功')),
      body: _buildBody(context),
    );
  }

  /// Builds main body.
  Widget _buildBody(BuildContext context) {
    return ListView(
      padding: const EdgeInsets.all(16.0),
      children: [
        const SizedBox(height: 30.0),
        const Icon(Icons.done, size: 80.0, color: Colors.green),
        Text(
          '账号注册成功',
          textAlign: TextAlign.center,
          style: Theme.of(context).textTheme.headlineSmall,
        ),
        const SizedBox(height: 30.0),
        Container(
          padding: const EdgeInsets.only(top: 20.0),
          height: 60.0,
          child: FilledButton.tonal(
            child: const Text(
              '去登录',
              style: TextStyle(fontSize: 20.0, color: Colors.white),
            ),
            // We need to use [pushNamedAndRemoveUntil] because we don't want user go back to another [PasswordLogin] once the back button pressed.
            // When we goes to [PasswordLogin] from here the navigation stack will contain two instance of it.
            // [pushNamedAndRemoveUntil] helps remove the previous and keep the current one.
            onPressed: () => NavigatorHelper.pushAndRemoveUntil(
              context,
              const PasswordLogin(),
              (route) => false,
            ),
          ),
        ),
      ],
    );
  }
}
